package nguyenquangminh.minigame;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Board extends JPanel implements ActionListener {
	private Basket basket;
	private Chicken chicken;
	private Duck duck;
	private Muscovy muscovy;
	private Egg egg;
	private Timer timer;
	private Game game;
	// Variables for gameplay
	private int speedEgg = 1;
	protected int score = 0;
	protected int life = 3;
	protected int level = 1;
	// Background images
	private BufferedImage background;
	private BufferedImage gameOver;
	
	// Constructor
	public Board() {
		URL backgroundUrl = this.getClass().getResource("/images/background.jpg");
		URL gameoverUrl = this.getClass().getResource("/images/gameover.jpg");
		try {
			background = ImageIO.read(backgroundUrl);
			gameOver = ImageIO.read(gameoverUrl);
		} catch (IOException e) {
			e.printStackTrace();
		}
		addKeyListener(new BoardKeyAdapter());
		addMouseMotionListener(new BoardMouseAdapter());
        setFocusable(true);
        basket = new Basket();
        chicken = new Chicken();
        duck = new Duck();
        muscovy = new Muscovy();
        timer = new Timer(5, this);
        timer.start();
	}
	
	// Paint method
	public void paint(Graphics g) {
		super.paint(g);
		if (life > 0) {
			Graphics2D g2d = (Graphics2D)g;
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			g2d.drawImage(background, 0, 0, 800, 600, null);
			basket.paint(g2d);
			chicken.paint(g2d);
			duck.paint(g2d);
			muscovy.paint(g2d);
			// Handle paint another Chicken object (event: G press)
			ArrayList chickenList = chicken.getChickenList();
	        for (int i = 0; i < chickenList.size(); i++ ) {
	            Chicken c = (Chicken) chickenList.get(i);
	            c.paint(g2d); 
	        }
	        // Handle paint another Duck object (event: V press)
 			ArrayList duckList = duck.getDuckList();
 	        for (int i = 0; i < duckList.size(); i++ ) {
 	            Duck d = (Duck) duckList.get(i);
 	            d.paint(g2d); 
 	        }
 	       // Handle paint another Muscovy duck object (event: N press)
 			ArrayList muscovyList = muscovy.getMuscovyList();
 	        for (int i = 0; i < muscovyList.size(); i++ ) {
 	            Muscovy m = (Muscovy) muscovyList.get(i);
 	            m.paint(g2d); 
 	        }
	        g2d.drawString("Your Score: " + score, 5, 20);
	        g2d.drawString("Your life: " + life, 5, 35);
	        g2d.drawString("Level: " + level, game.S_WIDTH - 60, 20);
		}
		else {
			Graphics2D g2d = (Graphics2D)g;
			g2d.drawImage(gameOver, 0, 0, 800, 600, null);
		}
		Toolkit.getDefaultToolkit().sync();
		g.dispose();
	} // End Paint method
	
	// Action performed method
	public void actionPerformed(ActionEvent e) {
		// Handle move another Chicken object (event: G press)
		ArrayList chickenList = chicken.getChickenList();
        for (int i = 0; i < chickenList.size(); i++) {
        	Chicken c = (Chicken) chickenList.get(i);
            c.move();
        }
        // Handle move another Duck object (event: V press)
        ArrayList duckList = duck.getDuckList();
        for (int i = 0; i < duckList.size(); i++ ) {
            Duck d = (Duck) duckList.get(i);
            d.move(); 
        }
        // Handle move another Muscovy duck object (event: N press)
        ArrayList muscovyList = muscovy.getMuscovyList();
        for (int i = 0; i < muscovyList.size(); i++ ) {
        	Muscovy m = (Muscovy) muscovyList.get(i);
            m.move(); 
        }
		basket.move();
		chicken.move();
		duck.move();
		muscovy.move();
		checkChickenCollision();
		checkDuckCollision();
		checkMuscovyCollision();
		repaint();
	} // End Action performed method
	
	/* Check Chicken collision method */
	public void checkChickenCollision() {
		Rectangle rBasket = basket.getBounds();
		ArrayList<Chicken> chickens = chicken.getChickenList();
		/* Check collision for the first chicken */
		// Check egg collision
		ArrayList<Egg> eggList = chicken.getEggsList();
        for (int j = 0; j<eggList.size(); j++) {
            Egg egg = (Egg) eggList.get(j);
            Rectangle rEgg = egg.getBounds();
            if (rBasket.intersects(rEgg)) {
            	eggList.remove(j);
            	score++;  
            	// Set level and speed game
            	int speed = egg.getSpeed();
            	if (score > 0 && score % 20 == 0) {
            		level++;
            		speed++;
            		egg.setSpeed(speed);
            		Shit.dy = egg.getSpeed();
            	}
            }
            if (egg.isVisible == false)
            	life--;
        }
        // Check shit collision
        ArrayList<Shit> shitsList = chicken.getShitsList();
        for (int j = 0; j<shitsList.size(); j++) {
        	Shit shit = (Shit) shitsList.get(j);     
            Rectangle rShit = shit.getBounds();
            if (rBasket.intersects(rShit)) {
            	shitsList.remove(j); 
            	life--;
            }           
        }
        /* Check collision for chickens in list */
        // Check egg collision
		for (int i = 0; i < chickens.size(); i++ ) {
	        Chicken c = (Chicken) chickens.get(i);
	        ArrayList<Egg> eggs = c.getEggsList();
	        for (int j = 0; j<eggs.size(); j++) {
	            Egg egg = (Egg) eggs.get(j);     
	            Rectangle rEgg = egg.getBounds();
	            if (rBasket.intersects(rEgg)) {
	            	eggs.remove(j);
	            	score++; 
	            	// Set level game
	            	int speed = egg.getSpeed();
	            	if (score > 0 && score % 20 == 0) {
	            		level++;
	            		speed++;
	            		egg.setSpeed(speed);
	            		Shit.dy = egg.getSpeed();
	            	}
	            }         
	            if (egg.isVisible == false)
	            	life--;
	        }
	        // Check shit collision
	        ArrayList<Shit> shits = c.getShitsList();
	        for (int j = 0; j<shits.size(); j++) {
	        	Shit shit = (Shit) shits.get(j);     
	            Rectangle rShit = shit.getBounds();
	            if (rBasket.intersects(rShit)) {
	            	shits.remove(j);  
	            	life--;
	            }           
	        }
	    }
	} // End check Chickens collision method
	
	/* Check Ducks collision */
	public void checkDuckCollision() {
		Rectangle rBasket = basket.getBounds();
		ArrayList<Duck> ducks = duck.getDuckList();
		/* Check collision for the first duck */
		// Check egg collision
		ArrayList<Egg> eggList = duck.getEggsList();
        for (int j = 0; j<eggList.size(); j++) {
            Egg egg = (Egg) eggList.get(j);
            Rectangle rEgg = egg.getBounds();
            if (rBasket.intersects(rEgg)) {
            	eggList.remove(j);
            	score++;  
            	// Set level game
            	int speed = egg.getSpeed();
            	if (score > 0 && score % 20 == 0) {
            		level++;
            		speed++;
            		egg.setSpeed(speed);
            		Shit.dy = egg.getSpeed();
            	}
            }
            if (egg.isVisible == false)
            	life--;
        }
        // Check shit collision
        ArrayList<Shit> shitsList = duck.getShitsList();
        for (int j = 0; j<shitsList.size(); j++) {
        	Shit shit = (Shit) shitsList.get(j);     
            Rectangle rShit = shit.getBounds();
            if (rBasket.intersects(rShit)) {
            	shitsList.remove(j); 
            	life--;
            }           
        }
        /* Check collision for ducks in list */
        // Check egg collision
		for (int i = 0; i < ducks.size(); i++ ) {
	        Duck d = (Duck) ducks.get(i);
	        ArrayList<Egg> eggs = d.getEggsList();
	        for (int j = 0; j<eggs.size(); j++) {
	            Egg egg = (Egg) eggs.get(j);     
	            Rectangle rEgg = egg.getBounds();
	            if (rBasket.intersects(rEgg)) {
	            	eggs.remove(j);
	            	score++; 
	            	// Set level game
	            	int speed = egg.getSpeed();
	            	if (score > 0 && score % 20 == 0) {
	            		level++;
	            		speed++;
	            		egg.setSpeed(speed);
	            		Shit.dy = egg.getSpeed();
	            	}
	            }         
	            if (egg.isVisible == false)
	            	life--;
	        }
	        // Check shit collision
	        ArrayList<Shit> shits = d.getShitsList();
	        for (int j = 0; j<shits.size(); j++) {
	        	Shit shit = (Shit) shits.get(j);     
	            Rectangle rShit = shit.getBounds();
	            if (rBasket.intersects(rShit)) {
	            	shits.remove(j);  
	            	life--;
	            }           
	        }
	    }
	} // End check Ducks collision method
	
	/* Check Muscovy ducks collision */
	public void checkMuscovyCollision() {
		Rectangle rBasket = basket.getBounds();
		ArrayList<Muscovy> muscovys = muscovy.getMuscovyList();
		/* Check collision for the first muscovy duck */
		// Check egg collision
		ArrayList<Egg> eggList = muscovy.getEggsList();
        for (int j = 0; j<eggList.size(); j++) {
            Egg egg = (Egg) eggList.get(j);
            Rectangle rEgg = egg.getBounds();
            if (rBasket.intersects(rEgg)) {
            	eggList.remove(j);
            	score++;  
            	// Set level game
            	int speed = egg.getSpeed();
            	if (score > 0 && score % 20 == 0) {
            		level++;
            		speed++;
            		egg.setSpeed(speed);
            		Shit.dy = egg.getSpeed();
            	}
            }
            if (egg.isVisible == false)
            	life--;
        }
        // Check shit collision
        ArrayList<Shit> shitsList = muscovy.getShitsList();
        for (int j = 0; j<shitsList.size(); j++) {
        	Shit shit = (Shit) shitsList.get(j);     
            Rectangle rShit = shit.getBounds();
            if (rBasket.intersects(rShit)) {
            	shitsList.remove(j); 
            	life--;
            }           
        }
        /* Check collision for muscovy ducks in list */
        // Check egg collision
		for (int i = 0; i < muscovys.size(); i++ ) {
	        Muscovy m = (Muscovy) muscovys.get(i);
	        ArrayList<Egg> eggs = m.getEggsList();
	        for (int j = 0; j<eggs.size(); j++) {
	            Egg egg = (Egg) eggs.get(j);     
	            Rectangle rEgg = egg.getBounds();
	            if (rBasket.intersects(rEgg)) {
	            	eggs.remove(j);
	            	score++; 
	            	// Set level game
	            	int speed = egg.getSpeed();
	            	if (score > 0 && score % 20 == 0) {
	            		level++;
	            		speed++;
	            		egg.setSpeed(speed);
	            		Shit.dy = egg.getSpeed();
	            	}
	            }         
	            if (egg.isVisible == false)
	            	life--;
	        }
	        // Check shit collision
	        ArrayList<Shit> shits = m.getShitsList();
	        for (int j = 0; j<shits.size(); j++) {
	        	Shit shit = (Shit) shits.get(j);     
	            Rectangle rShit = shit.getBounds();
	            if (rBasket.intersects(rShit)) {
	            	shits.remove(j);  
	            	life--;
	            }           
	        }
	    }
	} // End check Muscovy ducks collision method
	
	// Set Level game
	public void setLevelGame() {
		if (score > 0 && score % 20 == 0) {
			level++;
			speedEgg++;
			egg.setSpeed(speedEgg);
		}
	}
	
	// Handle keys event in game
	private class BoardKeyAdapter extends KeyAdapter {
		public void keyReleased(KeyEvent e) {
			basket.keyReleased(e);
		}
		
		public void keyPressed(KeyEvent e) {
			basket.keyPressed(e);
			chicken.keyPressed(e);
			duck.keyPressed(e);
			muscovy.keyPressed(e);
		}
	}
	
	// Handle mouse event in game
	private class BoardMouseAdapter extends MouseMotionAdapter {
		public void mouseMoved(MouseEvent e) {
			basket.mouseMoved(e);
		}
	}
}
